<?php
/**
 * 分页栏处理类
 * @package baseLib
 * @author 刘程辉 <shijun@staff.sina.com.cn>
 * @version 1.0
 * @copyright (c) 2005, 新浪网研发中心 All rights reserved.
 * @example ./page_bar.class.php 查看源代码
 * @example ./page_bar.example.php 如何使用请点这里
 */
class page_bar
{

	/**
	 * 分页时取得最大页
	 * @param $num			总计条数
	 * @param $perpage		单页条数
	 * @param $curpage		当前页
	 * @param $maxpages		允许的最大页
	 * @param $page
	 * @return unknown_type
	 */
	function get_page_max($num, $perpage, $curpage, $maxpages = 0, $page = 10)
	{
		$realpages = 1;
		$from = $to = 1;
		if($num > $perpage) 
		{
			$offset = 2;
	
			$realpages = @ceil($num / $perpage);
			$pages = $maxpages && $maxpages < $realpages ? $maxpages : $realpages;
	
			if($page > $pages) 
			{
				$from = 1;
				$to = $pages;
			} 
			else 
			{
				$from = $curpage - $offset;
				$to = $from + $page - 1;
				if($from < 1) 
				{
					$to = $curpage + 1 - $from;
					$from = 1;
					if($to - $from < $page) 
					{
						$to = $page;
					}
				} 
				elseif($to > $pages) 
				{
					$from = $pages - $page + 1;
					$to = $pages;
				}
			}
		}
		return $to;
	}
		
	
	/**
	 * 生成上一页，下一页的分页栏
	 * @return string;
	 * @param   array  $style 固定的数组格式，格式参考
     * 
     * $style = array(
     * 	'curt'		=> $_GET['p'],							// 当前页号
     * 	'max'		=> 20,									// 最大页号
     * 	'key'		=> 'p',									// 页号CGI的参数KEY
     * 	'up'		=> '上一页',							// 向上翻页的文字样式
     * 	'down'		=> '下一页',							// 向下翻页的文字样式
     * 	'tmpl'		=> '<a href="%s">%s</a>',				// 翻页链接的样式
     * 	'format'	=> '<<&nbsp;%s&nbsp;&nbsp;%s&nbsp;>>' 	// 最后输出的样式
     * );
     * 本函数必须传递的几个键值 curt, max。其余参数不填设置为默认项
	 */
	
	function bar1($style)
	{
		if(! isset($style['curt']) && ! is_numeric($style['curt']) && 
		   ! isset($style['max']) && ! is_numeric($style['max']) && 
		   ($style['curt'] > $style['max']))
		{
			return false;
		}

		$style['key'] 		= isset($style['key']) ? $style['key'] : 'p';
		$style['up'] 		= isset($style['up']) ? $style['up'] : '上一页';
		$style['down'] 		= isset($style['down']) ? $style['down'] : '下一页';
		$style['tmpl'] 		= isset($style['tmpl']) ? $style['tmpl'] : '<a href="%s">%s</a>';
		$style['format'] 	= isset($style['format']) ? $style['format'] : '<<&nbsp;%s&nbsp;&nbsp;%s&nbsp;>>';

		if( ! isset($style['curt']) && !is_numeric($style['curt']) && $style['curt'] < 1)
		{
			$style['curt'] = 1;
		}
	    $pre_url = page_bar::_repl_cgi($style['key'], ($style['curt'] - 1));

	    $nex_url = page_bar::_repl_cgi($style['key'], ($style['curt'] + 1));

		$pre_txt = ($style['curt'] > 1) ? sprintf($style['tmpl'], $pre_url, $style['up']) : $style['up'];

		$nex_txt = ($style['curt'] < $style['max']) ? sprintf($style['tmpl'], $nex_url, $style['down']) : $style['down'];

	    if ($style['curt'] >= 1)
	    {
	        return sprintf($style['format'], $pre_txt, $nex_txt); 
	    }
	}

	/** 
	 * 生成分页导航栏：导航栏样式 "第8页 共60页 &laquo;第一个 < 4 5 6 7 8 9 10 11 12 > 最后的&raquo; "
	 * @return 	string
	 * @param	integer	$curt_page	当前页
	 * 			integer	$max_page	最大页
	 *			integer	$step_len	当前页的前后显示页的数量，缺省值为4
	 */
	function bar2($style)
	{
		if(! isset($style['curt']) && ! is_numeric($style['curt']) && 
		   ! isset($style['max']) && ! is_numeric($style['max']) && 
		   ($style['curt'] > $style['max']))
		{
			return false;
		}

		$style['key'] 		= isset($style['key']) ? $style['key'] : 'p';
		$style['len'] 		= isset($style['len']) ? $style['len'] : 4;
		$style['up'] 		= isset($style['up']) ? $style['up'] : '&laquo;第一个';
		$style['down'] 		= isset($style['down']) ? $style['down'] : '最后的&raquo;';

		$pre_bar = "";
		$end_bar = "";
		$bar = "";
		if ($style['max'] > 1)
		{
			$this_begin = page_bar::_bar2_pre_step($style['curt'], $style['len']);
			$this_end 	= page_bar::_bar2_next_step($style['curt'], $style['len'], $style['max']);
			for ($i = $this_begin; $i <= $this_end; $i++)
			{
				if ($i == $style['curt'])
				{
					$bar .= page_bar::_bar2_curt_page_style($i);
				}
				else
				{
					$bar .= page_bar::_bar2_page_style($style['key'], $i);
				}
			}

			if($style['curt'] > 1)
			{
				$pre_bar = page_bar::_bar2_page_style($style['key'], $style['curt'] - 1 , "&lt;");
				if ($this_begin > 1)
				{
					$pre_bar = page_bar::_bar2_page_style($style['key'], 1, $style['up']) . $pre_bar;

				}
			}
			if($style['curt'] < $style['max'])
			{
				$end_bar =  page_bar::_bar2_page_style($style['key'], $style['curt'] + 1 , "&gt;");

				if ($this_end < $style['max'])
				{
					$end_bar .= page_bar::_bar2_page_style($style['key'], $style['max'],  $style['down']);
				}
			}
		}
		elseif ($style['max'] = 1)
		{
			$bar  = page_bar::_bar2_curt_page_style("1");
		}
		return $pre_bar . $bar . $end_bar;
	}

	/**
	 * BAR2 生成当除当前页外的其他页面的链接
	 * @param integer	$num	页号
	 * 		  string	$txt	页号需要显示的内容,缺省值为页号
	 */
	function _bar2_page_style($key, $num, $txt = "")
	{
		if ($txt == "")
		{
			return "<a href=\"" . page_bar::_repl_cgi($key, $num) . "\">{$num}</a>&nbsp;";
		}
		else
		{
			return "<a href=\"" . page_bar::_repl_cgi($key, $num) . "\">{$txt}</a>&nbsp;";
		}
	}

	/**
	 * BAR2 生成当前页的链接
	 * @param integer	$num	页号
	 */
	function _bar2_curt_page_style($num)
	{
		return "<span style=\"color:red;font-weight:bold;\">{$num}</span>&nbsp;";
	}

	/**
	 * 取向前$len页的页号
	 * @param integer	$curt	当前页号
	 * 		  integer	$len	向前的长度
	 */
	function _bar2_pre_step($curt, $len)
	{
		return ($curt - $len < 1) ? 1 : ($curt - $len);
	}

	/**
	 * 取向后$len页的页号
	 * @param integer	$curt	当前页号
	 * 		  integer	$len	向前的长度
	 *		  integer	$end	最大页号
	 */
	function _bar2_next_step($curt, $len, $end)
	{
		return ($curt + $len > $end) ? $end : ($curt + $len);
	}


	/** 
	 * 生成分页导航栏：导航栏样式 "上十页 1 2 3 4 5 6 7 8 9 下十页"
	 * @return 	string
	 * @param	integer	$curt_page	当前页
	 * 			integer	$max_page	最大页
	 *			integer	$step_len	当前页的前后显示页的数量，缺省值为4
	 */
	function bar3($style,$bdate="",$edate="")
	{
		if(! isset($style['curt']) && ! is_numeric($style['curt']) && 
		   ! isset($style['max']) && ! is_numeric($style['max']) && 
		   ($style['curt'] > $style['max']))
		{
			return false;
		}
		
		$style['key'] 		= isset($style['key']) ? $style['key'] : 'p';
		$style['len'] 		= isset($style['len']) ? $style['len'] : 10;
		$style['up'] 		= isset($style['up']) ? $style['up'] : '&laquo;';
		$style['down'] 		= isset($style['down']) ? $style['down'] : '&raquo;';
		
		if ($style['max'] > 1)
		{
			$this_begin = page_bar::_bar3_pre_step($style['curt'], $style['len']);
			$this_end 	= page_bar::_bar3_next_step($this_begin, $style['len'], $style['max']);
			for ($i = $this_begin; $i <= $this_end; $i++)
			{
				if ($i == $style['curt'])
				{
					$bar .= page_bar::_bar3_curt_page_style($i);
				}
				else
				{
					$bar .= page_bar::_bar3_page_style($style['key'], $i, "", $bdate, $edate);
				}
			}
			if($this_begin > $style['len'])
			{
				$pre_bar = page_bar::_bar3_page_style($style['key'], $this_begin - $style['len'], $style['up']);
			}
			if($this_end < $style['max'])
			{
				$end_bar = page_bar::_bar3_page_style($style['key'], $this_begin + $style['len'], $style['down']);
			}
		}
		else if ($max_page = 1)
		{
			$bar  = page_bar::_bar3_curt_page_style("1");
		}
		return $pre_bar . $bar . $end_bar;
	}

	function bar4($style)
	{
		if(! isset($style['curt']) && ! is_numeric($style['curt']) && 
		   ! isset($style['max']) && ! is_numeric($style['max']) && 
		   ($style['curt'] > $style['max']))
		{
			return false;
		}

		$style['key'] 		= isset($style['key']) ? $style['key'] : 'p';
		$style['up'] 		= isset($style['up']) ? $style['up'] : '上一页';
		$style['down'] 		= isset($style['down']) ? $style['down'] : '下一页';
		$style['tmpl'] 		= isset($style['tmpl']) ? $style['tmpl'] : '<a href="%s">%s</a>';
		$style['format'] 	= isset($style['format']) ? $style['format'] : '<<&nbsp;%s&nbsp;&nbsp;%s&nbsp;>>';

		if( ! isset($style['curt']) && !is_numeric($style['curt']) && $style['curt'] < 1)
		{
			$style['curt'] = 1;
		}
	    $pre_url = page_bar::_repl_cgi($style['key'], ($style['curt'] - 1));

	    $nex_url = page_bar::_repl_cgi($style['key'], ($style['curt'] + 1));

		$pre_txt = ($style['curt'] > 1) ? sprintf($style['tmpl'], $pre_url, $style['up']) : $style['up'];

		$nex_txt = ($style['curt'] < $style['max']) ? sprintf($style['tmpl'], $nex_url, $style['down']) : $style['down'];

	    if ($style['curt'] >= 1)
	    {
	        return sprintf($style['format'], $pre_txt, $style['curt'], $style['max'], $nex_txt); 
	    }
	}

	/**
	 * 生成当除当前页外的其他页面的链接
	 * @param string	$key	页号的CGI KEY值
	 *		  integer	$num	页号
	 * 		  string	$txt	页号需要显示的内容,缺省值为页号
	 */
	function _bar3_page_style($key, $num, $txt = "", $bdate="", $edate="")
	{
		if ($txt == "")
		{
			if(!empty($bdate) && !empty($edate))
			{
				$data_str = "&bdate={$bdate}&edate={$edate}";
			}
			return "<a href=\"" . page_bar::_repl_cgi($key, $num) . "{$data_str}\">{$num}</a>&nbsp;";
		}
		else
		{
			if(!empty($bdate) && !empty($edate))
			{
				$data_str = "&bdate={$bdate}&edate={$edate}";
			}
			return "<a href=\"" . page_bar::_repl_cgi($key, $num) . "{$data_str}\">{$txt}</a>&nbsp;";
		}
	}

	/**
	 * 生成当前页的链接
	 * @param integer	$num	页号
	 */
	function _bar3_curt_page_style($num)
	{
		return "<span style=\"color:red;font-weight:bold;\">{$num}</span>&nbsp;";
	}

	/**
	 * 取向前$len页的页号
	 * @param integer	$curt	当前页号
	 * 		  integer	$len	向前的长度
	 */
	function _bar3_pre_step($curt, $len)
	{
		if ($curt % $len)
		{
			$pre = floor($curt / $len) * $len;
		}
		else
		{
			$pre = (floor($curt / $len) - 1) * $len;
		}
		return (int)$pre + 1;
	}

	/**
	 * 取向后$len页的页号
	 * @param integer	$curt	当前页号
	 * 		  integer	$len	向前的长度
	 *		  integer	$end	最大页号
	 */
	function _bar3_next_step($curt, $len, $end)
	{
		return ($curt + $len > $end) ? $end : ($curt + $len - 1);
	}

	/**
	 * 替换CGI参数，如果CGI中参数存在则替换该值，如果不存在则在CGI末尾添加
	 * @return string;
	 * @param   string  key cgi参数key
	 *          string  val cgi参数key的对应值
	 */
	function _repl_cgi($key, $val)
	{
        global $host_string, $query_string;
        
        $sname  = $_SERVER['SCRIPT_NAME'];
        $qstr   = $_SERVER['QUERY_STRING'];
        $qarry  = array();
        
        if($qstr == "")
        {
            return $sname . "?{$key}={$val}";
        }

        parse_str($qstr, $qarry);

        if (array_key_exists($key, $qarry))
        {
            $qarry[$key] = "{$val}";
            $new_qstr = "?";
            foreach ($qarry as $k => $v)
            {
				$new_qstr .= $k . "=" . $v . "&";
            }
            $new_qstr = rtrim( $new_qstr, "&");
            return $sname . $new_qstr;
        }
        return $sname . "?" . $qstr . "&{$key}={$val}";
	}
}
?>